package datastructures;

import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;

/**
 * Simulace systemove heapy
 * @author honzee
 */
public class SystemHeap {

    private final Map<Integer, Object> heap;
    private Integer pointer;

    public SystemHeap() {
        this.heap = new HashMap<Integer, Object>();
        pointer = 0;
    }

    /**
     * Ulozi na heapu string
     */
    public Integer putString(String str) {
        pointer++;
        heap.put(pointer, str);

        return pointer;
    }

    /**
     * Precte z heapy string
     */
    public String getString(Integer pointer) {
        return (String) heap.get(pointer);
    }

    /**
     * Alokuje na heape nove pole s danym poctem dimenzi
     */
    public Integer putArray(int[] dimensions) {
        pointer++;
        Object o = Array.newInstance(Integer.class, dimensions);
        heap.put(pointer, o);

        return pointer;
    }

    /**
     * Nastavuje polozku daneho pole na danych souradnicich
     */
    public void putValueIntoArray(Integer pointer, int[] dimensions,
            Integer value) {
        Object o = heap.get(pointer);
        for (int i = 0; i < dimensions.length; i++) {
            if (i == dimensions.length-1) {
                Integer[] a = (Integer[]) o;
                a[dimensions[i]] = value;
            } else {
                o = Array.get(o, dimensions[i]);
            }
        }
    }

    /**
     * Vraci polozku daneho pole z danych souradnic
     */
    public Integer getValueFromArray(Integer pointer, int[] dimensions) {
        Object o = heap.get(pointer);
        Integer value = null;
        for (int i = 0; i < dimensions.length; i++) {
            if (i == dimensions.length-1) {
                Integer[] a = (Integer[]) o;
                value = a[dimensions[i]];
            } else {
                o = Array.get(o, dimensions[i]);
            }
        }
        return value;
    }

    /**
     * Dealokuje misto na heape
     */
    public void dealloc(Integer pointer) {
        heap.remove(pointer);
    }
}